/*
 * @brief statistics accumulator (implementation file)
 *
 * @note
 * Copyright(C) NXP Semiconductors, 2015
 * All rights reserved.
 *
 * @par
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * LPC products.  This software is supplied "AS IS" without any warranties of
 * any kind, and NXP Semiconductors and its licensor disclaim any and
 * all warranties, express or implied, including all implied warranties of
 * merchantability, fitness for a particular purpose and non-infringement of
 * intellectual property rights.  NXP Semiconductors assumes no responsibility
 * or liability for the use of the software, conveys no license or rights under any
 * patent, copyright, mask work right, or any other intellectual property rights in
 * or to any products. NXP Semiconductors reserves the right to make changes
 * in the software without notification. NXP Semiconductors also makes no
 * representation or warranty that such application will be suitable for the
 * specified use without further testing or modification.
 *
 * @par
 * Permission to use, copy, modify, and distribute this software and its
 * documentation is hereby granted, under NXP Semiconductors' and its
 * licensor's relevant copyrights in the software, without fee, provided that it
 * is used in conjunction with NXP Semiconductors microcontrollers.  This
 * copyright, permission, and disclaimer notice must appear in all copies of
 * this code.
 */

#include <stdio.h>
#include <process.h>
#include <stdint.h>
#include <stdbool.h>
#include <windows.h>

#include "lpcusbsio.h"
#include "hostif_protocol.h"

#include "trace.h"
#include "stat_acc.h"

static uint16_t		stat_arr[STAT_ACC_SZ];
static uint16_t		stat_arr_idx	= 0;
static uint32_t		acc_ct			= 0;
static uint32_t		acc_low			= ~0L;
static uint32_t		acc_high		= 0;

/*
--------------------------------------------------------------------------------
	stat_acc_init

	Initialize all statistics / accumulation variables
--------------------------------------------------------------------------------
 */
void stat_acc_init(void)
{
	memset(stat_arr, 0, STAT_ACC_SZ);											/* clear accumulator array */
	stat_arr_idx	= 0;														/* reset index */
	acc_ct			= 0;														/* clear overall count */
	acc_low			= ~0L;														/* max-out global low value */
	acc_high		= 0;														/* clear global high value */
}

/*
--------------------------------------------------------------------------------
	stat_acc_process

	Process a data element (de)
--------------------------------------------------------------------------------
 */
void stat_acc_process(uint16_t de)
{
	stat_arr[stat_arr_idx++] = de;												/* save the data element */
	if (stat_arr_idx == STAT_ACC_SZ) stat_arr_idx = 0;							/* bump / roll idx as necessary */
	acc_ct += 1;																/* bump packet count */

	if (acc_low > de) acc_low = de;												/* calculate global low value */
	if (acc_high < de) acc_high = de;											/* calculate global high value */
}

/*
--------------------------------------------------------------------------------
	stat_acc_dump

	Dump accumulated data to stdout.
--------------------------------------------------------------------------------
 */
void stat_acc_dump(void)
{
	uint32_t i, low, high, curr_idx;

	high = low = stat_arr[0];													/* set high and low to initial values */
	curr_idx = (stat_arr_idx == 0) ? STAT_ACC_SZ-1 : stat_arr_idx-1;			/* initialize current index */
	printf("I2C block information:");											/* print display */

	if (acc_ct == 0) {															/* if no packets received... */
		printf(" no packets received\n");										/* notify user */
		return;																	/* exit function */
	}

	for (i=0; i<STAT_ACC_SZ; i++) {												/* loop through data blocks */
		if ((i % 16) == 0)	printf("\n%04d:", i);								/* print a left edge offset value (decimal) */
		if (i == curr_idx)														/* if printing current value... */
			printf("*%-4d", stat_arr[i]);										/* mark it with an asterisk */
		else																	/* if not... */
			printf(" %-4d", stat_arr[i]);										/* print it normally */
		if (low > stat_arr[i]) low = stat_arr[i];								/* calculate low value */
		if (high < stat_arr[i]) high = stat_arr[i];								/* calculate high value */
	}
	printf("\n");																/* LF after data */
	printf("Global data:\n");													/* print global data header */
	printf("- packet count:%d\n",acc_ct);										/* print total packet count */
	printf("- low:%d high:%d\n",acc_low,acc_high);								/* print global limits */

	printf("Buffer data:\n");													/* print data header */
	printf("- buffer index:%d\n",curr_idx);										/* print buffer index */
	printf("- low:%d high:%d current:%d\n",low,high,stat_arr[curr_idx]);		/* print current limits & position */
}
